﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlServerCe;

namespace Shared
{
    internal class KeyMatcher
    {

        private static Dictionary<string, IndexColumn[]> _indexColumnsLookup = new Dictionary<string, IndexColumn[]>(1);

        private IndexColumn[] _indexColumns;

        private struct IndexColumn
        {
            public int Ordinal;
            public bool IsString;
        }

        private static IndexColumn[] CreateIndexDetails(SqlCeConnection cnn, string tableName, string indexName, SqlCeDataReader resultSet)
        {
            return DatabaseInfo.GetData(cnn)
                    .Where(ix => ix.IndexName.Equals(indexName) && ix.TableName.Equals(tableName, StringComparison.OrdinalIgnoreCase))
                    .OrderBy(ix => ix.Ordinal)
                    .Select(ix => new IndexColumn() { Ordinal = resultSet.GetOrdinal(ix.ColumnName), IsString = resultSet.GetFieldType(resultSet.GetOrdinal(ix.ColumnName)) == typeof(string) })
                    .ToArray();
        }

        internal static KeyMatcher CreateKeyMatcher(SqlCeConnection cnn, string tableName, string indexName, SqlCeDataReader resultSet)
        {
            string key = string.Concat(cnn.ConnectionString, tableName, ":", indexName);

            IndexColumn[] kmm;
            if (!_indexColumnsLookup.TryGetValue(key, out kmm))
            {
                Dictionary<string, IndexColumn[]> no = new Dictionary<string, IndexColumn[]>(_indexColumnsLookup);
                no[key] = kmm = CreateIndexDetails(cnn, tableName, indexName, resultSet);
                System.Threading.Interlocked.Exchange(ref _indexColumnsLookup, no);
            }

            return new KeyMatcher() { _indexColumns = kmm, _resultSet = resultSet };
        }

        private SqlCeDataReader _resultSet;

        public bool KeyMatches(object[] keyValues)
        {
            for (int i = 0; i < keyValues.Length; i++)
            {
                object kv = keyValues[i];
                if (kv == null) return false;
                if (i == _indexColumns.Length) return true;//shouldnothappen

                object v = _resultSet[_indexColumns[i].Ordinal];
                if (v == DBNull.Value) return false;
                if (_indexColumns[i].IsString)
                {
                    if (!((string)v).Equals((string)kv, StringComparison.OrdinalIgnoreCase)) return false;
                }
                else
                {
                    if (!v.Equals(kv)) return false;
                }
            }


            return true;
        }



    }
}
